home *** CD-ROM | disk | FTP | other *** search
- /*
- * MB.C - 9/20/92 - MailBox mainline code.
- */
-
- /*
- * Copyright (C) 1987, 1988
- * On Modules by H. N. Oredson
- * Copyright (C) 1988, 1989, 1990, 1991, 1992
- * By the CBBS Group.
- *
- * It is being developed by the CBBS Group.
- * It may be freely copied for non-commercial use,
- * as long as this notice is retained.
- *
- * This notice and Copyright apply to all modules
- * referenced by this module.
- *
- */
-
- #include "mb.h"
-
- #ifdef MCH_AMIGA
- extern char conn_direction;
- #ifndef MCH_SYSOP
- extern PORTS *devtnc;
- #endif
- #include "lock.h"
-
- /* Allow user to specify the device name and unit number if they have
- a multi-serial card. But default it to the standard device on unit zero
- If ser_dev_name is zero then ser.c will use the standard name.
- */
- char *ser_dev_name = 0L;
- long unit = -1L;
-
- extern short kambbs, thebox, debug , tapr_flag;
- long BaudRate;
- short left = 0, top = 0, width = 640, height = 256;
- extern int daylight;
- #else
- char *ver = "\nC-BBS V7.2, 20 SEP 1992\n\n";
- char *vers = "[CBBS-7.20-H$]\n";
- #endif
- char *nullstr = "";
-
- PORTS *porthd = NULL;
- PORTS *cport = NULL;
- PORTS *port;
-
- int scrmax, dirmax, log_mon;
- TMP *tmp;
- MLM *motd;
- char *helpfile, *infofile;
- char *bbmenu, *symenu, *rmenus, *mumsg;
- char *reqmsg, *qth, *keylst;
- char *mcant, *mdone, *mfind, *mexst, *mnfile, *mnmsg;
- char *mprot, *mtime, *mwhat, *mnport, *mndir, *minuse;
- char achar, rchar, tchar, wchar;
- word s_param, p_window, c_flag, b_flag;
- byte s_mart, s_prompt, s_flag, unt_hr;
- char scmd[24];
-
- #ifdef MCH_AMIGA
- #ifndef MCH_SYSOP
- char hostport = 'A';
- #else
- char hostport = '1';
- #endif
- #endif
-
- #ifdef MCH_AMIGA
- short timezone = -900; /* Initialize to impossible number of minutes */
- extern char tmpstr[];
- #endif
- main(argc, argv)
- int argc;
- char *argv[];
- {
- #ifdef MCH_AMIGA
- char *cp;
- short i;
-
- /* Might as well do a quick check to make sure the locker is there.
- */
- if(FindPort((UBYTE *)LOCK_NAME) == 0L) {
- printf("Can't find the locker process\n");
- exit(10);
- }
- /* Get the environment variable timezone if it is set.
- Doing it here allows the user to override the value of TZ_CHU
- with the -z argument.
- */
- timezone = gettz("");
- get_reject();
- while(argc > 1) {
- if(argv[1][0] == '-') {
- switch(tolower(argv[1][1])) {
-
- /* allow user to specify the position of the window on the screen
- -wL/T/W/H
- */
- case 'w':
- cp = &argv[1][2];
- left = atoi(cp);
- while(*cp && (*cp != '/'))cp++;
- if(*cp == 0)break;
- cp++;
- top = atoi(cp);
- while(*cp && (*cp != '/'))cp++;
- if(*cp == 0)break;
- cp++;
- width = atoi(cp);
- while(*cp && (*cp != '/'))cp++;
- if(*cp == 0)break;
- cp++;
- height = atoi(cp);
- setwindow(left,top,width,height);
- break;
-
- /* In multi mode, specify the port which this copy will open
- */
- case 'p':
- hostport = toupper(argv[1][2]);
- break;
-
- case 'n': /* Serial port name for multi-serial users */
- ser_dev_name = &argv[1][2];
- break;
- case 'u': /* Serial port unit number for multi-serial */
- unit = (long)atoi(&argv[1][2]);
- break;
-
- case 'd':
- debug = 1;
- break;
- /* Baud rate is in the host driver */
- case 'b':
- BaudRate = atol(&argv[1][2]);
- break;
- case 't':
- /* tell serial read routine to strip high bit off all bytes
- read from the TNC because it is a TAPR upgrade kit that
- generates NO parity only with the parity bit forced to one
- */
- tapr_flag++;
- break;
- case 'z':
- /* Specify the timezone so that you can keep your amiga
- on your local time but have the time in messages converted
- to UTC. format is -z[-]hh[:mm][d]
- Times WEST of Greenwich are POSITIVE.
- Times EAST of Greenwich are NEgative.
- The optional minutes ":mm" allows places like Newfoundland
- to specify their zone as 3:30.
- If the optional letter 'd' is present at the end of the
- string, then your local time zone is adjusted for daylight
- savings time.
-
- The -z argument, if set, overrides any value in the TZ_CHU
- environment variable.
- */
- timezone = gettz(&argv[1][2]);
- break;
- }
- argc--;
- argv++;
- continue;
- }
- break;
- }
- /* Just make sure that there isn't already a port with our name on it */
- if(testport()) {
- exit(1);
- }
- /* Call routine that reads my modified init() so that the config.mb
- file is opened early to permit options in config.mb to be read
- before the window and serial port are opened. This allows options
- to be used that affect the opening of the window or serial parameters.
- */
- if (argc > 1)i = setinit(argv[1]); else i = setinit("config.mb");
- if(i)exit(1);
- printf("Serial device name = %s unit = %ld\n",ser_dev_name,unit);
- if(initser()) {
- printf("error opening serial port\n");
- exit(1);
- }
- if(openterm()) {
- printf("error opening terminal\n");
- cleanser();
- exit(1);
- }
-
- if(inittimer()) {
- printf("error opening timer\n");
- cleanser();
- closeterm();
- exit(1);
- }
-
- /* This does more than the quick check at the beginning of main() so
- don't remove this call.
- */
- if(i = findlock()) {
- printf("Can't find the Lock process - %d\n",i);
- cleanser();
- closeterm();
- exit(1);
- }
- /* This allows the port driver to count how many processes are running
- without having to be told
- */
- setbusy();
-
- /* Up to this point all routines MUST do their own cleaning up and then
- exit() directly. AFTER setbusy() has been called any further errors
- should cause done() to be called because done() calls clrbusy.
- Otherwise the locking program will have an incorrect count of the number
- of active processes.
- The EXCEPTION to this rule is inittnc() which already cleared up its
- own mess, so I just added a clrbusy as well, rather than try to fix
- it up to use done().
- */
-
- #endif
-
-
- if (argc > 1) init(argv[1]); else init("config.mb");
-
- #ifdef MCH_AMIGA
- /* Compute the first Sunday in April and last Sunday in October
- if daylight savings is being used.
- */
- dstdates();
- if(timezone != -900) {
- i = timezone;
- sprintf(tmpstr,"Timezone = %c%d:%02d %s\n",
- i<0?'-':' ',i<0?-i/60:i/60,i<0?(-i)%60:i%60,
- daylight?"(DST)":"");
- ttputs(tmpstr);
- printf("%s",tmpstr);
- i = dst(timezone);
- if(i != timezone) {
- sprintf(tmpstr,"DST time = %c%d:%02d\n",
- i<0?'-':' ',i<0?-i/60:i/60,i<0?(-i)%60:i%60);
- ttputs(tmpstr);
- printf("%s",tmpstr);
- }
- }
- else {
- cp = "Timezone not set - Assume UTC and no DST\n";
- printf("%s",cp);
- ttputs(cp);
- timezone = 0;
- daylight = 0;
- }
- #endif
-
-
- #ifdef MCH_AMIGA
- /* Open up the AREXX public port so that the waitport program can be used
- to start up several CBBS copies in sequence and also allows communication
- from outside processes and between multiple 'mb' processes.
- */
- if(open_rexx())done(1);
- #endif
- while (true)
- {
- s_mart = 0;
- #ifdef MCH_AMIGA
- kambbs = 0;
- thebox = 0;
- conn_direction = ' ';
- user_title("");
- titles();
- #endif
- do_idle();
- setbusy();
- login();
- #ifndef MCH_AMIGA
- if (!(port->mode & exclude)) do_cmds();
- #else
- /*FIX 8 ignore idle terminal caused by monitoring data that looks like a
- "*** CONNected" message.
- */
- if(!(port->mode & idle)) {
- if(!(port->mode & exclude)) do_cmds();
- }
- #endif
- logo();
- }
- }
-
- do_cmds()
- {
- register PORTS *p;
- register char *i, *o;
-
- p = port;
-
- while(true)
- {
- prompt();
- getcmd();
- if (p->mode & gone) return;
-
- /*
- * Console broke in on a user?
- */
-
- if (p->flags & p_opreq)
- {
- p->flags clrbit p_opreq;
- prtx(talkm1);
- if (p->tmode)
- {
- cmdtnc();
- convtnc();
- }
- ioport(cport);
- prtx(mumsg);
- cport->fl = NULL;
- term(p);
- ioport(p);
- tncstate();
- if (p->tmode) trantnc(); else convtnc();
- if (p->mode & gone) return;
- }
-
- /*
- * Check for LINK.
- * Require "LINKED to" to be first command.
- */
-
- else if (islink(p->line))
- {
- if (p->cmdcnt) p->msg = mwhat; else
- {
- strcpy(p->line, p->line + 14);
- logina(true);
- remnl(p->line);
- log('C', 'L', ' ', p->line);
- if (p->mode & exclude) return;
- }
- }
-
- /*
- * Must be a command.
- */
-
- else
- {
- docmd();
- if (p->errors > p->errmax) p->mode = forced;
- if (p->mode & (gone | idle | logout)) return;
- }
- }
- }
-
- /*
- * Q command: exit to DOS.
- */
-
- #ifndef MCH_AMIGA
- done()
- {
- byte pflg;
-
- if (sure()) return;
- #else
- extern short done_flag;
- done(askflag)
- int askflag;
- {
- byte pflg;
- if(!askflag && sure()) return;
- done_flag = 0;
- cursor_off();
- close_rexx();
- #endif
- upduser(cport->user);
- log('X', 'Q', ' ', nullstr);
- clslog();
- clsusr();
- clsmsg();
- clsmon();
- iooff();
- clrbusy();
- pflg = getp_flag();
- putp_flag(pflg clrbit p_window);
- #ifdef MCH_AMIGA
- endtimer();
- cleanser();
- freefcb();
- closeterm();
- stoplock();
- #endif
- exit(0);
- }
-
- /*
- * Give the user a prompt.
- */
-
- prompt()
- {
- register PORTS *p, *tp;
-
- p = port;
- if (p->msg isnt NULL) prtx(p->msg);
- p->msg = NULL;
-
- /*
- * Tell sysop who this is.
- */
-
- if (p isnt cport) { ioport(cport); prtx(mumsg); ioport(p); }
-
- /*
- * Show any connect request seen on the user port.
- */
-
- if (p->flags & p_req) prtx(reqmsg);
- p->flags clrbit p_req;
-
- /*
- * Bleed off any connect requests on other ports.
- */
-
- /* There aren't any other ports on the AMIGA */
- #ifndef MCH_AMIGA
- for (tp = porthd; tp isnt NULL; tp = tp->next) if (tp->mode & idle)
- if ((tp->dev is p_tnc) and (tp isnt p))
- {
- ioport(tp);
- while (instat()) getdat();
- }
- ioport(p);
- #endif
- /*
- * Display the prompt.
- */
-
- curtim();
- switch (p->mode)
- {
- case local :
- case sysop :
- prtx(symenu);
- break;
-
- case remote:
- if (!(p->user->options & u_bbs))
- {
- if (s_prompt & s_p_name) if (!(p->user->state & u_name)) prtx(um[4]);
- if (s_prompt & s_p_home) if (!(p->user->state & u_home)) prtx(um[5]);
- if (s_prompt & s_p_zip) if (!(p->user->state & u_zip)) prtx(um[6]);
- if (s_prompt & s_p_qth) if (!(p->user->state & u_qth)) prtx(um[7]);
- }
-
- #ifndef MCH_AMIGA
- if (p->user->options & (u_bbs | u_expert)) prtx(bbmenu); else prtx(rmenus);
- #else
- if(p->user->options & u_bbs) outstr(">\n");
- else if (p->user->options & u_expert) prtx(bbmenu);
- else prtx(rmenus);
- #endif
- break;
- }
- }
-
- /*
- * Log the user off.
- * Do any defered remote sysop command.
- */
-
- logo()
- {
- register PORTS *p;
- register PORTS *tp;
- register char t;
-
- p = port;
-
- switch(p->mode)
- {
- case idle : t = 'A'; break; /* Init bbs logout */
- case logout : t = 'B'; break;
- case discon : t = 'D'; break;
- case exclude: t = 'E'; break;
- case forced : t = 'F'; distnc(); break;
- case timeout: t = 'T'; prtx(mtime); break;
- default : t = '?'; break;
- }
-
- #ifndef MCH_AMIGA
- log('X', t, ' ', nullstr);
- #else
- log('X', t, port->id , nullstr);
- #endif
-
- /*
- * If any port was used in terminal mode by the console,
- * disconnect it.
- */
-
- if (p->dev is p_console)
- for (tp = porthd; tp isnt NULL; tp = tp->next)
- if (tp->flags & p_term)
- {
- ioport(tp);
- tp->mode = remote;
- distnc();
- tp->mode = idle;
- tp->flags clrbit p_term;
- }
-
- ioport(p);
-
- /*
- * Change TNC back to "standard" if was in "sysop" mode.
- * May have just THOUGHT we discon, REALLY disconnect.
- */
-
- if (p->dev is p_tnc)
- {
- if (p->flags & p_clrsys) mkrem();
- p->mode = remote;
- distnc();
- }
- if (p->dev is p_serial) p->flags clrbit p_trans;
- #ifdef MCH_AMIGA
- if (p->dev is p_nulmdm) p->flags clrbit p_trans;
- #endif
- #ifndef MCH_SYSOP
- /* Hang up a modem */
- if(p->dev is p_serial) {
- force_modem();
- }
- /* If it was the console but the serial device is a modem, then allow
- phone to ring again.
- */
- if(p->dev is p_console) {
- if(devtnc->dev is p_serial) {
- tp = p;
- ioport(devtnc);
- outstr("ATS0=2\n");
- waitcmd(2);
- ioport(tp);
- }
- }
- #endif
- p->mode = idle;
-
- upduser(p->user);
-
- /*
- * If there was a "defered remote sysop command" do it.
- */
-
- ioport(cport);
- if (s_param & s_cmd)
- {
- s_param clrbit s_cmd;
- strcpy(cport->line, scmd);
- parse();
- wait(10); /* Give sysop chance to get HIS system online */
- cport->mode = local; /* Do command as if console did it */
- docmd();
- cport->mode = idle;
- }
-
- clnlog();
- clsusr();
- setfwd();
- clsmsg();
- }
-
- /*
- * MailBox is idle.
- * See if there is anything to do, and do it.
- * If nothing to do, wait for connect.
- */
-
- #ifndef MCH_AMIGA
- do_idle()
- {
- register PORTS *p;
- register short curmin, lastmin, curmon;
-
- for (p = porthd; p isnt NULL; p = p->next) p->ec = p->ecmon;
-
- getc_flag();
- if (c_flag & p_window) acmd();
-
- allon(); /* Turn on monitoring and connects */
- clrbusy();
- curtim();
- curmin = 10 * (l_time[2] - '0') + (l_time[3] - '0');
- while(true)
- {
-
- /*
- * Check the port command flag to see if another window has
- * issued a command request. If so setup and do the command.
- */
-
- getc_flag();
- if (c_flag & p_window)
- {
- setbusy();
- alloff();
- acmd();
- allon();
- clrbusy();
- }
-
- lastmin = curmin;
- curtim();
- curmin = 10 * (l_time[2] - '0') + (l_time[3] - '0');
- curmon = 10 * (l_date[2] - '0') + (l_date[3] - '0');
-
- /*
- * Once each minute:
- * Forward now, if it is time on any port.
- */
-
- if (curmin isnt lastmin) afwd(curmin);
- if (s_param & s_log_on) if (curmon isnt log_mon) chglog();
-
- /*
- * Look for a login.
- */
-
- for (p = porthd; p isnt NULL; p = p->next)
- {
- ioport(p);
- if (instat()) switch(p->dev)
- {
- case p_serial:
- p->flags clrbit p_give;
- getdat();
- p->flags setbit p_give;
- if (iscon(p->line)) return;
- break;
-
- case p_tnc:
- p->flags clrbit p_give;
- getdat();
- p->flags setbit p_give;
- if (iscon(p->line)) return;
- monitor();
- break;
-
- case p_console:
- if (inchar() is wchar) return;
- break;
- }
- p->flags setbit p_give;
- }
- }
- }
- #endif
- /*
- * Do commands retrieved from the bios.
- */
- #ifndef MCH_AMIGA
- acmd()
- {
- char need_msg = false;
- char notime = false;
-
- port->mode = local;
- getcomd();
- if (s_flag & s_dv) begin_lock();
- if (isdigit(port->opt2))
- {
- notime = true;
- port->opt2 = port->opt2 ^ 0x70;
- }
- if ((port->opt1 is 'X') and (findport(port->opt2)))
- {
- if (notime) port->opt2 = ' '; else port->opt2 = 'I';
- readmsg();
- readusr();
- need_msg = true;
- }
- getc_flag();
- putc_flag( c_flag clrbit p_window);
- if (s_flag & s_dv) end_lock();
- if (need_msg or (port->opt2 is 'H'))
- {
- sprintf(port->line, "%c%c", port->opt1, port->opt2);
- parse();
- docmd();
- }
- if (need_msg)
- {
- clnlog();
- setfwd();
- clsmsg();
- clsusr();
- }
- port->mode = idle;
- }
- #endif
- #ifdef MCH_AMIGA
- #ifndef MCH_SYSOP
- acmd()
- {
- char need_msg = false;
- char notime = false;
- port->mode = local;
- if (s_flag & s_dv) begin_lock();
- if(port->opt1 == 'X')
- {
- readmsg();
- readusr();
- need_msg = true;
- }
- if (s_flag & s_dv) end_lock();
- if (need_msg or (port->opt2 is 'H'))
- {
- sprintf(port->line, "%c%c", port->opt1, port->opt2);
- parse();
- docmd();
- }
- if (need_msg)
- {
- clnlog();
- setfwd();
- clsmsg();
- clsusr();
- }
- port->mode = idle;
- }
- #endif
- #endif
- /* Bring this here from mbfwd to save having to make a separate sysop
- version of mbfwd (Otherwise it could stay there)
- */
- #ifdef MCH_SYSOP
- all_fwd()
- {
- word pflg;
- port->opt1 = 'X';
- putcomd( port->opt1, port->opt2 );
- #ifndef MCH_AMIGA
- pflg = getp_flag();
- putc_flag (pflg);
- #endif
- port->mode = logout;
- }
- #endif
-